package ray.mgocc.title;

import java.text.ParseException;
import ray.mgocc.Record;
import ray.mgocc.Time;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;

public abstract class Title extends ArrayList<Requirement> implements Comparable<Title>{
    private Record record = null;
    private Time playTimeThreshold = null;
    private PlayTimeRequirement playtime = null;
    private Map<String,Object> param = new HashMap<String,Object>();
    public void setRecord(Record record){
        this.record = record;
    }
    protected Record getRecord(){
        return this.record;
    }
    public boolean check(){
        init();
        boolean check = true;
        for(Requirement sample:this){
            if(!sample.check()){
                check = false;
            }
        }
        return check;
    }
    public String getName(){
        return getClass().getSimpleName();
    }
    abstract public int getPriority();
    abstract protected int getPlayTimeThreshold();
    abstract protected Time getPlayTime();
    public void init(){
        clear();
        getParam().clear();

        PlayTimeRequirement threshold = new PlayTimeRequirement(getPlayTimeThreshold());
        threshold.setPlayTime(getPlayTime());
        add(threshold);
    }
    public Map<String,Object> getParam(){
        return this.param;
    }
    protected Object getParam(String key){
        Object value;
        Map param = getParam();
        value = param.get(key);
        if(null==value){
            value = getRecord().getValue(key);
            param.put(key,value);
        }
        return value;
    }
    public int getValue(String key){
        return ((Integer)getParam(key)).intValue();
    }
    public Time getTime(String key){
        return (Time)getParam(key);
    }
    public String toString(){
        return getName();
    }
    public double percent(){
        Requirement min = Collections.min(this);
        return min.percent();
    }
    public String details(){
        init();
        StringBuilder s = new StringBuilder();
        s.append(toString()).append(" ");
        s.append(check());
        s.append("[").append(percent()).append("%").append("]");

        for(Requirement require:this){
            s.append(" ").append(require);
        }
        s.append(getParam());
        return s.toString();
    }
    public int compareTo(Title that){
        // 優先度が小さい方が先に来るので注意。
        return that.getPriority() - this.getPriority();
    }


    protected void addRoundRequirement(int threshold,String rule){
        add(new RoundRequirement(threshold,rule));
    }
    class RoundRequirement extends Requirement{
        private int threshold;
        private String rule;
        public RoundRequirement(int threshold,String rule){
            this.threshold = threshold;
            this.rule = rule;
        }
        public String getName(){return "round("+getRule()+")";}
        public int getThreshold(){ return threshold; }
        public String getRule(){return this.rule;}
        private int getRound(){
            final String KEY = rule+".";
            int round = getValue(KEY+"ROUND");
            return round;
        }
        public double getRatio(){
            return ((double)getRound()) / getThreshold();
        }
        public String toString(){
            return super.toString()+"("+getThreshold()+"<="+getRound()+")";
        }
    }
}
